package net.tyw.core.auth;

import com.alibaba.fastjson.JSON;
import net.tyw.common.utils.DateUtil;
import net.tyw.common.utils.ValidateUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.text.MessageFormat;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.TimeUnit;

@Component
public class OauthServiceImpl extends OauthService {

    private final String OAUTH_REDIS_KEY = "SYSTEM:OAUTHUSER:{0}";
    private final String AUTHORITIES_REDIS_KEY = "SYSTEM:AUTHORITIES:{0}";

    /**
     * 登录失效时间2小时
     */
    private final int expire = 60 * 60 * 24;


    @Autowired
    private RedisTemplate<String, String> stringRedisTemplate;

    @Override
    public void setAuth(String sessionId, OauthUser oauthUser) {
        String redisKeySid = MessageFormat.format(OAUTH_REDIS_KEY, sessionId);

        this.stringRedisTemplate.boundValueOps(redisKeySid).set(JSON.toJSONString(oauthUser), expire, TimeUnit.SECONDS);
    }

    @Override
    public OauthUser getOAuth(String sessionId) {
        OauthUser oauthUser = null;
        if (ValidateUtil.isNoneBlank(sessionId)) {
            String redisKeySid = MessageFormat.format(OAUTH_REDIS_KEY, sessionId);
            String jsonOauthUser = this.stringRedisTemplate.boundValueOps(redisKeySid).get();
            oauthUser = JSON.parseObject(jsonOauthUser, OauthUser.class);
            if (oauthUser != null && sessionId.equals(oauthUser.getSessionId())) {
                this.stringRedisTemplate.expire(redisKeySid, expire, TimeUnit.SECONDS);
            }
        }

        if (oauthUser == null) {
            oauthUser = OauthUser.instance(0L, "匿名用户", DateUtil.current(), sessionId);
        }
        return oauthUser;
    }


    @Override
    public void destroy(String sessionId) {
        //销毁登录信息
        this.stringRedisTemplate.delete(MessageFormat.format(OAUTH_REDIS_KEY, sessionId));
        this.stringRedisTemplate.delete(MessageFormat.format(AUTHORITIES_REDIS_KEY, sessionId));
    }

    @Override
    public void setAuthorities(String sessionId, Set<String> listAuthorities) {
        String redisKey = MessageFormat.format(AUTHORITIES_REDIS_KEY, sessionId);
        if (listAuthorities == null || listAuthorities.isEmpty()) {
            this.stringRedisTemplate.delete(redisKey);
        } else {
            String[] arrayAuthorities = listAuthorities.toArray(new String[0]);
            this.stringRedisTemplate.boundSetOps(redisKey).add(arrayAuthorities);
        }
    }

    @Override
    public boolean hasAuthority(String sessionId, String authority) {
        String redisKey = MessageFormat.format(AUTHORITIES_REDIS_KEY, sessionId);

        if (StringUtils.isBlank(sessionId) || StringUtils.isBlank(authority)) {
            return false;
        }
        boolean result = this.stringRedisTemplate.boundSetOps(redisKey).isMember(authority.trim());
        if (result) {
            this.stringRedisTemplate.expire(redisKey, expire, TimeUnit.SECONDS);
        }
        return result;
    }

    @Override
    public Set<String> getAuthorities(String sessionId) {
        String redisKey = MessageFormat.format(AUTHORITIES_REDIS_KEY, sessionId);
        Set<String> listAuthorities = this.stringRedisTemplate.boundSetOps(redisKey).members();
        if (listAuthorities == null) {
            listAuthorities = new HashSet<>();
        }
        return listAuthorities;
    }
}
